package com.dlc.shop.api.controller;

import com.alipay.api.AlipayApiException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.dlc.shop.bean.app.dto.RegiserMemberDTO;
import com.dlc.shop.bean.app.param.PayUserParam;
import com.dlc.shop.bean.enums.PayEntry;
import com.dlc.shop.bean.model.ShopCustomer;
import com.dlc.shop.bean.model.UserExtension;
import com.dlc.shop.bean.pay.PayInfoDto;
import com.dlc.shop.common.allinpay.constant.AllinpayConstant;
import com.dlc.shop.common.bean.PaySettlementConfig;
import com.dlc.shop.common.config.Constant;
import com.dlc.shop.common.constants.SegmentIdKey;
import com.dlc.shop.common.exception.YamiShopBindException;
import com.dlc.shop.common.response.ServerResponseEntity;
import com.dlc.shop.manager.impl.PayManager;
import com.dlc.shop.security.api.model.YamiUser;
import com.dlc.shop.security.api.util.SecurityUtils;
import com.dlc.shop.security.common.bo.LoginInfoBO;
import com.dlc.shop.security.common.manager.TokenStore;
import com.dlc.shop.security.common.util.AuthUserContext;
import com.dlc.shop.service.*;
import com.dlc.shop.user.common.enums.RecruitStatusEnum;
import com.dlc.shop.user.common.model.UserLevel;
import com.dlc.shop.user.common.model.UserLevelLog;
import com.dlc.shop.user.common.service.UserLevelLogService;
import com.dlc.shop.user.common.service.UserLevelService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.Objects;

/**
 * @author LHD on 2020/03/02.
 */
@Tag(name = "会员购买接口")
@RestController
@RequestMapping("/p/level")
@AllArgsConstructor
public class PayLevelController {

    private final UserLevelService userLevelService;
    private final UserExtensionService userExtensionService;
    private final UserLevelLogService userLevelLogService;
    private final PayManager payManager;
    private final PayInfoService payInfoService;
    private final SegmentService segmentService;
    private final ShopCustomerService shopCustomerService;
    private final SysConfigService sysConfigService;
    private final TokenStore tokenStore;

    /**
     * 会员支付接口
     */
    @PostMapping("/payLevel")
    @Operation(summary = "根据会员等级进行支付" , description = "根据会员等级进行支付")
    @SneakyThrows({WxPayException.class, AlipayApiException.class})
    public ServerResponseEntity<?> payVip(HttpServletResponse httpResponse, @RequestBody PayUserParam payCardParam) {
        String userId = AuthUserContext.getUserId();
        UserExtension userExtension = userExtensionService.getOne(new LambdaQueryWrapper<UserExtension>()
                                            .eq(UserExtension::getUserId, userId));
        UserLevel userLevel = userLevelService.getById(payCardParam.getId());

        //如果会员等级为空
        if(userLevel == null || !Objects.equals(userLevel.getLevelType(),1)) {
            // 会员等级不存在或当前等级不为付费会员等级！
            throw new YamiShopBindException("yami.user.level.no.exist");
        }
        if(Objects.nonNull(userLevel.getRecruitStatus()) && Objects.equals(userLevel.getRecruitStatus(), RecruitStatusEnum.STOP_RECRUIT.value())) {
            // 当前会员等级已经停止招募,不能进行购买
            throw new YamiShopBindException("yami.pay.level.recruit.status");
        }
        if(Objects.equals(userExtension.getLevelType(),1) && userExtension.getLevel() > userLevel.getLevel()){
            // 用户无法在会员期间购买低等级会员
            throw new YamiShopBindException("yami.user.pay.level.check");
        }
        if(userExtension.getGrowth() < userLevel.getNeedGrowth()){
            // 用户成长值不足，无法购买
            throw new YamiShopBindException("yami.user.growh.no.enough");
        }

        String payNo = String.valueOf(segmentService.getDateFormatSegmentId(SegmentIdKey.PAY));
        // 查询支付系统类型
        PaySettlementConfig config = sysConfigService.getSysConfigObject(Constant.PAY_SETTLEMENT_CONFIG, PaySettlementConfig.class);
        Integer paySysType = config.getPaySettlementType();
        Date now = new Date();
        //生成等级日志
        UserLevelLog userLevelLog = new UserLevelLog();
        userLevelLog.setGiftTime(now);
        userLevelLog.setCreateTime(now);
        userLevelLog.setLevel(userLevel.getLevel());
        userLevelLog.setState(0);
        userLevelLog.setPayNo(payNo);
        userLevelLog.setIsPayed(0);
        userLevelLog.setPayAmount(userLevel.getNeedAmount());
        userLevelLog.setLevelName(userLevel.getLevelName());
        userLevelLog.setTerm(userLevel.getTerm());
        userLevelLog.setTermType(userLevel.getTermType());
        userLevelLog.setPayType(payCardParam.getPayType());
        userLevelLog.setUserId(userExtension.getUserId());
        userLevelLog.setShopId(Constant.PLATFORM_SHOP_ID);
        userLevelLog.setPaySysType(paySysType);
        //插入一条等级日志
        userLevelLogService.save(userLevelLog);
        payCardParam.setPayNo(payNo);
        payCardParam.setOrderIds(userLevelLog.getLevelLogId());
        payCardParam.setNeedAmount(userLevel.getNeedAmount());
        PayInfoDto payInfo = payInfoService.buyVip(userId, payCardParam);

        LoginInfoBO loginInfo = tokenStore.getLoginInfoByCache();
        if (loginInfo!=null) {
            payInfo.setBizUserId(loginInfo.getBizUserId());
        }
        payInfo.setAllinpayUserId(AllinpayConstant.USER + userId);
        payInfo.setPayType(payCardParam.getPayType());
        payInfo.setApiNoticeUrl("/notice/pay/" + paySysType + "/" + PayEntry.VIP.value() + "/" + payCardParam.getPayType());
        payInfo.setReturnUrl(payCardParam.getReturnUrl());
        payInfo.setPaySysType(paySysType);
        payInfo.setSystemType(payCardParam.getSystemType());
        payInfo.setValidateType(payCardParam.getValidateType());
        payInfo.setUserId(payInfo.getUserId());
        return payManager.doPay(httpResponse, payInfo);
    }

    @GetMapping("/isPay")
    public ServerResponseEntity<Integer> isPay(){
        YamiUser user = SecurityUtils.getUser();
        UserLevelLog uLog = userLevelLogService.getMaxCrtTimeByUserId(user.getUserId());
        return ServerResponseEntity.success(uLog.getIsPayed());
    }

    @PostMapping("/registerFreeMember")
    @Operation(summary = "注册成为店铺免费会员", description =  "注册成为店铺免费会员")
    public ServerResponseEntity<Void> registerFreeMember(@RequestBody RegiserMemberDTO regiserMemberDTO) {
        Long shopId = regiserMemberDTO.getShopId();
        // 数据库数据校验
        String userId = SecurityUtils.getUser().getUserId();
        ShopCustomer shopCustomer = shopCustomerService.getOne(new LambdaQueryWrapper<ShopCustomer>()
                .eq(ShopCustomer::getShopId, shopId)
                .eq(ShopCustomer::getUserId, userId));
        if (shopCustomer != null
                && shopCustomer.getLevelType() != -1) {
            throw new YamiShopBindException("yami.user.member.exception.hasBeenShopMember");
        }
        // 注册会员
        if (shopCustomer == null) {
            shopCustomer = new ShopCustomer();
        }
        UserLevel level = userLevelService.getOne(new LambdaQueryWrapper<UserLevel>()
                .eq(UserLevel::getLevelType, 0)
                .eq(UserLevel::getShopId, shopId)
                .orderByAsc(UserLevel::getNeedGrowth)
                .last("limit 1"));
        shopCustomer.setMemberName(regiserMemberDTO.getMemberName());
        shopCustomer.setUserId(userId);
        shopCustomer.setShopId(shopId);
        shopCustomer.setGrowth(0);
        shopCustomer.setLevelId(level.getId());
        shopCustomer.setLevel(level.getLevel());
        shopCustomer.setLevelType(0);
        shopCustomer.setRegistTime(new Date());
        shopCustomerService.saveOrUpdate(shopCustomer);
        return ServerResponseEntity.success();
    }
}
